<?php

require_once "config.php";
require_once "funcs.php";

class Wechat
{
    public $conn;

    public function setConn($con)
    {
        $this->conn = $con;
    }
    function __construct($con = null)
    {
        if($con != null){
            $this->conn = $con;
        }
    }

    public function getAccessToken() //获取access_token
    {
        global $CONFIG;
        $appid = $CONFIG['appid'];
        $secret = $CONFIG['secret'];
        $token = "unknown";

        //先看库里有的是否过期
        $result = mysql_query("select * from weixin_token where appID='$appid' and expireTime > now()",
            $this->conn);
        if (is_resource($result) && mysql_num_rows($result) != 0) {
            $row = mysql_fetch_array($result, MYSQL_ASSOC);
            $token = $row['token'];
        } else {
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
            $data = enhancedFetchUrlContent("unknown", $url, "获取token", "getToken", $this->
            conn, 2, false); //通过自定义函数getCurl得到https的内容
            $resultArr = json_decode($data, true); //转为数组
            if (isset($resultArr["access_token"])) {
                $token = $resultArr["access_token"]; //获取access_token
                $expires_in = $resultArr["expires_in"];
                $sql = "insert into weixin_token (appID, secret, token, expireTime, updateTime) ";
                $sql .= "values ('$appid', '$secret', '$token', (now() + interval $expires_in second), now()) ";
                $sql .= " on DUPLICATE KEY UPDATE token='$token', expireTime=(now() + interval $expires_in second), updateTime = now();";
                mysql_query($sql, $this->conn);
            }
        }

        return $token;
    }

    public function creatMenu() //创建菜单
    {
        global $CONFIG;

        $data = array();
        $result = mysql_query("select id, parentNode, nodeName,shortName, responseMessageID, responseType, comment from weixin_node order by cast(concat(nodeLevel, shortname) as SIGNED INTEGER) asc",
            $this->conn);
        //select id, parentNode, nodeName,shortName, responseMessageID, responseType from weixin_node where weixin_account_id = 'huggies' order by concat(nodeLevel, shortname) asc
        while ($arr = mysql_fetch_array($result, MYSQL_ASSOC)) {
            $data[] = array(
                'id' => $arr['id'],
                'fid' => $arr['parentNode'],
                'name' => $arr['nodeName'],
                'messageID' => $arr['responseMessageID'],
                'comment' => $arr['comment'],
                'type' => $arr['responseType']);
        }

        $tree = arr2tree($data);

        //var_dump($resultArr['rst']);

        $buttons = array();
        foreach ($tree as $temp) {
            $leaf = array();
            if (!isset($temp['children'])) {
                if ($temp["type"] != 'link') //处理click菜单
                {
                    $type = "click";
                    $name = urlencode($temp["name"]);
                    $key = $temp["id"] . "_" . $temp["messageID"];
                    $leaf["type"] = $type;
                    $leaf["name"] = $name;
                    $leaf["key"] = $key;
                } else //处理view菜单
                {
                    $type = "view";
                    $name = urlencode($temp["name"]);
                    $url = $temp["comment"];
                    $leaf["type"] = $type;
                    $leaf["name"] = $name;
                    $leaf["url"] = $url;
                }
            } else {
                $name_1 = urlencode($temp["name"]);
                $subButtons = array();
                foreach ($temp['children'] as $child) {
                    $subButton = array();
                    if ($child["type"] != 'link') //处理click菜单
                    {
                        $type = "click";
                        $name = urlencode($child["name"]);
                        $key = $child["id"] . "_" . $child["messageID"];
                        $subButton["type"] = $type;
                        $subButton["name"] = $name;
                        $subButton["key"] = $key;
                    } else {
                        $type = "view";
                        $name = urlencode($child["name"]);
                        $url = $child["comment"];
                        $subButton["type"] = $type;
                        $subButton["name"] = $name;
                        $subButton["url"] = $url;
                    }
                    $subButtons[] = $subButton;
                }
                $leaf["name"] = $name_1;
                $leaf["sub_button"] = $subButtons;
            }
            $buttons[] = $leaf;
        }

        //var_dump($buttons);
        $menuPostString = '{"button":' . urldecode(json_encode($buttons)) . '}';

        echo "$menuPostString";
        $accessToken = $this->getAccessToken(); //获取access_token
        $menuPostUrl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" . $accessToken; //POST的url
        $menu = dataPost($menuPostString, $menuPostUrl); //将菜单结构体POST给微信服务器
        echo "<br>$menuPostUrl<br>";
        echo $menu;
    }

    public function getFansList() //获取关注者列表
    {
        global $CONFIG;

        $fansList = array();
        $fansCount = 0;
        $next_openid = 'first';
        $accessToken = $this->getAccessToken(); //获取access_token
        while ($next_openid != '') {
            $fansListUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" . $accessToken; //&next_openid=NEXT_OPENID
            if ($next_openid != 'first') {
                $fansListUrl .= "&next_openid=" . $next_openid;
            }
            $result = json_decode(fetchUrlContent($fansListUrl), true);
            echo "<br>$fansListUrl<br>";
            $fansCount = $result['total'];
            $next_openid = $result['next_openid'];

            if ((int)$result['count'] > 0 && isset($result['data'])) {
                $temp = $result['data'];
                foreach ($temp['openid'] as $tempOpenID) {
                    $fansList[$tempOpenID] = $tempOpenID;
                }
            }
        }
        //print_r($fansList);
        if (count($fansList) > 0) {
            $crd = 1;
            foreach ($fansList as $openid) {
                $accessToken = $this->getAccessToken();
                $fansInfo = $this->getFansInfo($openid, $accessToken, $this->conn, true);
                //print_r($fansInfo);

                if (isset($fansInfo['errmsg'])) {
                    $errmsg = $fansInfo['errmsg'];
                    echo date("Y-m-d H:i:s") . "\t$crd\t$openid\t$errmsg\t$accessToken<br>\n";
                } else {
                    $nickname = mysql_real_escape_string($fansInfo['nickname'], $this->conn);
                    echo date("Y-m-d H:i:s") . "\t$crd\t$openid\t$nickname\t$accessToken<br>\n";
                }
                $crd++;
                //break;
            }
        }
        echo "------------------------------------------------------------------------------<br>\n";
    }

    public function getFansInfo($openid, $accessToken, $conn, $updateDatabase = false)
        //获取关注者基本信息
    {
        global $CONFIG;

        $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" . $accessToken .
            "&openid=$openid";
        $temp = fetchUrlContent($url);
        $fansInfo = json_decode($temp, true);
        $error = json_last_error();
        if ($error === JSON_ERROR_CTRL_CHAR) {
            $jsonError = mysql_real_escape_string($error . " " . $temp);
            $sql = "insert into weixin_nickname (fromUsername, weixinNick, firstAddTime, updateTime, jsonError)";
            $sql .= "values ('$openid', '$openid', now(), now(), '$jsonError') ";
            $sql .= " ON DUPLICATE KEY UPDATE updateTime = now(), jsonError = '$jsonError'";
            mysql_query("$sql", $this->conn);

            //解决 JSON_ERROR_CTRL_CHAR 错误
            $fansInfo = json_decode(preg_replace('/[[:cntrl:]]/u', '', $temp), true);
        }
        if ($updateDatabase) //如果需要更新数据库的话
        {
            $error = json_last_error();
            if ($error === JSON_ERROR_NONE) {
                if (isset($fansInfo['subscribe'])) {
                    $subscribe = $fansInfo['subscribe'];
                    if ($subscribe == 0) {
                        $sql = "insert into weixin_nickname (fromUsername, weixinNick, firstAddTime, updateTime)";
                        $sql .= "values ('$openid', '$openid', now(), now()) ";
                        $sql .= " ON DUPLICATE KEY UPDATE subscribe=$subscribe, updateTime = now() ";
                        mysql_query("$sql", $this->conn);
                    } else {
                        $nickname = mysql_real_escape_string($fansInfo['nickname']);
                        $sex = $fansInfo['sex']; // 1男 2女 0未知
                        $language = mysql_real_escape_string($fansInfo['language']);
                        $city = mysql_real_escape_string($fansInfo['city']);
                        $country = mysql_real_escape_string($fansInfo['country']);
                        $province = mysql_real_escape_string($fansInfo['province']);
                        $headimgurl = mysql_real_escape_string($fansInfo['headimgurl']);
                        $subscribe_time = date("Y-m-d H:i:s", $fansInfo['subscribe_time']); //最后一次关注时间

                        $sql = "insert into weixin_nickname (fromUsername, weixinNick, subscribe, sex, language, city, province, country, headimgurl, subscribe_time, firstAddTime, updateTime) ";
                        $sql .= "values ('$openid', '$nickname', $subscribe, $sex, '$language', '$city', '$province', '$country', '$headimgurl', '$subscribe_time', '$subscribe_time', now()) ";
                        $sql .= " ON DUPLICATE KEY UPDATE subscribe=$subscribe, weixinNick='$nickname', sex=$sex, language='$language', city='$city', ";
                        $sql .= "province='$province', country='$country', headimgurl='$headimgurl', subscribe_time='$subscribe_time', updateTime=now();";
                        mysql_query("$sql", $this->conn);

                        //通知腾讯更新
                        //todo:通知腾讯更新
                        if ($CONFIG['vendor'] == 'huggies123') {
                            $sql = "insert into needsRefresh (fromUsername, src, createTime) ";
                            $sql .= "values ('$openid', 'getuser', now()) ";
                            mysql_query("$sql", $this->conn);
                        }
                    }
                } else {
                    if (isset($fansInfo['errmsg']) && $fansInfo['errcode'] == "40001") {
                        global $CONFIG;
                        $appid = $CONFIG['appid'];
                        $secret = $CONFIG['secret'];
                        $token = "unknown";

                        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
                        $data = enhancedFetchUrlContent("unknown", $url, "token失效更新token", "getToken", $this->
                        conn, 2, false); //通过自定义函数getCurl得到https的内容
                        $resultArr = json_decode($data, true); //转为数组

                        if (isset($resultArr["access_token"])) {
                            $token = $resultArr["access_token"]; //获取access_token
                            $expires_in = $resultArr["expires_in"];
                            $sql = "insert into weixin_token (appID, secret, token, expireTime, updateTime) ";
                            $sql .= "values ('$appid', '$secret', '$token', (now() + interval $expires_in second), now()) ";
                            $sql .= " on DUPLICATE KEY UPDATE token='$token', expireTime=(now() + interval $expires_in second), updateTime = now();";
                            mysql_query($sql, $this->conn);
                        }
                    }
                }

                //以下更新缓存
                $sql = "select * from weixin_nickname where fromUsername = '$openid';";
                $query = mysql_query($sql, $this->conn);
                $row = mysql_fetch_assoc($query);
                if ($row) {
                    unset($row['jsonError']);
                    $jsonValue = json_encode_cn($row);
                }


            }

        }
        return $fansInfo;
        /*
        {
        "subscribe": 1,
        "openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
        "nickname": "Band",
        "sex": 1,
        "language": "zh_CN",
        "city": "广州",
        "province": "广东",
        "country": "中国",
        "headimgurl":    "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
        "subscribe_time": 1382694957
        }
        */
    }

    public function updateMissAccounts() //刷新未进入weixin_nickname表的openid信息
    {
        global $CONFIG;
        $conn = connect_to_db();
        $accessToken = $this->getAccessToken(); //获取access_token

        $existIDs = array();
        $sql = "select fromUsername from weixin_nickname;";
        $result = mysql_query($sql, $this->conn);
        while ($arr = mysql_fetch_array($result, MYSQL_ASSOC)) {
            $openid = $arr['fromUsername'];
            $existIDs[$openid] = $openid;
        }

        $stateIDs = array();
        $sql = "select fromUsername from weixin_states;";
        $result = mysql_query($sql, $this->conn);
        while ($arr = mysql_fetch_array($result, MYSQL_ASSOC)) {
            $openid = $arr['fromUsername'];
            $stateIDs[$openid] = $openid;
        }

        $crd = 1;
        foreach ($stateIDs as $openid) {
            //未更新
            if (!isset($existIDs[$openid])) {
                $fansInfo = $this->getFansInfo($openid, $accessToken, $conn, true);
                $nickname = isset($fansInfo['nickname']) ? mysql_real_escape_string($fansInfo['nickname']) :
                    "unknown";
                echo "$crd\t$openid\t$nickname<br>\n";
            }
            $crd++;
        }
    }

    public function updateAccount($fromUsername) //刷新openid信息
    {
        global $CONFIG;
        $accessToken = $this->getAccessToken(); //获取access_token

        $fansInfo = $this->getFansInfo($fromUsername, $accessToken, $this->conn, true);
        $nickname = isset($fansInfo['nickname']) ? mysql_real_escape_string($fansInfo['nickname']) :
            "unknown";
        echo "$fromUsername\t$nickname<br>\n";
        print_r($fansInfo);
    }

    public function createQrcode($is_returnOBJ=false,$comment='') //生成二维码
    {
        global $CONFIG;
        $showInfo = array();
        $comment = mysql_real_escape_string($comment);
        $accessToken = $this->getAccessToken(); //获取access_token

        $sql = "select max(scene_id) as id from weixin_qrcode;";
        $result = mysql_query($sql, $this->conn);
        $oldID = 0;
        if (is_resource($result) && mysql_num_rows($result) != 0) {
            $row = mysql_fetch_array($result, MYSQL_ASSOC);
            $oldID = $row['id'];
        }

        $newID = $oldID + 1;

        $action_info = array("scene" => array("scene_id" => $newID));
        $postData = json_encode(array("action_name" => "QR_LIMIT_SCENE", "action_info" =>
            $action_info));


        $qrPostUrl = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $accessToken; //POST的url
        $result = json_decode(dataPost($postData, $qrPostUrl), true); //将菜单结构体POST给微信服务器
        $showInfo['postData']=$postData;
//        $showInfo['qrPostUrl']=$qrPostUrl;
        $showInfo['result']=$result;
        if (isset($result['ticket'])) {
            $ticket = $result['ticket'];
            $picUrl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=$ticket";
            $sql = "insert into weixin_qrcode (action_name, scene_id, ticket, picUrl, createTime,comment) ";
            $sql .= "values ('QR_LIMIT_SCENE', $newID, '$ticket', '$picUrl', now(),'$comment') ";
            $sql .= " ON DUPLICATE KEY UPDATE ticket='$ticket', picUrl='$picUrl', createTime=now();";
            mysql_query("$sql", $this->conn);
            $showInfo['result']['picUrl'] = $picUrl;
            $showInfo['result']['newID'] = $newID;
        }
        if($is_returnOBJ == false){
            var_dump($showInfo);
        }else{
            return $showInfo;
        }

        //{"ticket":"gQGu8DoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL1hFeEQ2Z2ZtMzR1bVlvb3BRR0FwAAIE2SOPUgMEAAAAAA=="}
    }

    public function updateFansStatus() //获取关注者列表
    {
        global $CONFIG;

        $fansList = array();
        $fansCount = 0;
        $next_openid = 'first';
        $accessToken = $this->getAccessToken(); //获取access_token
        while ($next_openid != '') {
            $fansListUrl = "https://api.weixin.qq.com/cgi-bin/user/get?access_token=" . $accessToken; //&next_openid=NEXT_OPENID
            if ($next_openid != 'first') {
                $fansListUrl .= "&next_openid=" . $next_openid;
            }
            $result = json_decode(fetchUrlContent($fansListUrl), true);
            echo "<br>$fansListUrl<br>";
            $fansCount = $result['total'];
            $next_openid = $result['next_openid'];

            if ((int)$result['count'] > 0 && isset($result['data'])) {
                $temp = $result['data'];
                foreach ($temp['openid'] as $tempOpenID) {
                    $fansList[$tempOpenID] = $tempOpenID;
                }
            }
        }
        //print_r($fansList);
        if (count($fansList) > 0) {
            $crd = 1;
            foreach ($fansList as $openid) {
                $sql = "insert into weixin_nickname (fromUsername, weixinNick, subscribe, subscribe_time, firstAddTime, updateTime, comment) ";
                $sql .= "values ('$openid', '$openid', 1, now(), now(), now(), 'addByFansList') ";
                $sql .= " ON DUPLICATE KEY UPDATE subscribe=1,subscribe_time=now(), updateTime=now() ";
                mysql_query($sql, $this->conn);
                echo "$crd\t$openid\tsubscribed<br>\n";
                $crd++;
                //break;
                //以下更新缓存
                $sql = "select * from weixin_nickname where fromUsername = '$openid';";
                $query = mysql_query($sql, $this->conn);
                $row = mysql_fetch_assoc($query);
                if ($row) {
                    unset($row['jsonError']);
                    $jsonValue = json_encode_cn($row);
                    $cache = getMemcachedConnection();
                    $key = $CONFIG['CACHE']['PREFIX'] . $openid;
                    $ret = @$cache->set($key, $jsonValue, time() + $CONFIG['CACHE']['LIFETIME']);
                    //var_dump($ret);
                }
            }
        }
        echo "------------------------------------------------------------------------------<br>\n";
    }

    /**发送模板消息
     * @param string $openid 接受模板消息的用户
     * @param string $tamplate_id 模板id
     * @param array $data 模板字段字典
     * @param string $url 点击模板消息后跳转的页面url
     */
    public function sendTplMsg($openid, $templateid, array $data, $redictUrl,$comment)
    {

        $sendUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $this->getAccessToken();//获取链接
        $touser = $openid;
        $url = $redictUrl;
        $template_id = $templateid;
        $param = compact('template_id', 'touser', 'url', 'data');
        $content = json_encode_cn($param);
        $result = dataPost($content, $sendUrl);
        $ret_json = json_decode($result, true);
        $msg_id = '';
        $comment = $comment===null?'':$comment;


        if (isset($ret_json['errcode']) && $ret_json['errcode'] == 0) {
            $sendOk = 1;
            $msg_id = $ret_json['msgid'];
        }else{
            $sendOk = 0;
        }
        $insert_sql = "INSERT INTO weixin_tplMsg_log (touser_openid,msg_id,content,result,is_send,send_time,comment) VALUE ('$touser','$msg_id','$content','$result','$sendOk',now(),'$comment')";
        mysql_query($insert_sql, $this->conn);

        return $sendOk;
    }
}
?>